package com.codermn.demo713;

import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;

/**
 * 用管道流实现生产者和消费者问题
 * @author jxau_scf
 * @date 2021/7/13 - 19:25
 */
public class ThreadTest {
    public static void main(String[] args) throws IOException {
        Goods goods = new Goods();
        Producer producer = new Producer(goods);
        Consumer consumer = new Consumer(goods);
        producer.start();
        consumer.start();

    }

    static class Producer extends Thread {
        Goods goods = null;
        public Producer(Goods goods) {
            this.goods = goods;
        }

        @Override
        public void run() {
            for (int i = 0;i < 10;i++){
                try {
                    Thread.sleep(1000);
                    goods.put(i);
                    System.out.println("Producer put "+i);
                } catch (IOException | InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    static class Consumer extends Thread{
        Goods goods = null;
        public Consumer(Goods goods){
            this.goods = goods;
        }

        @Override
        public void run() {
            while (true){
                try {
                    Thread.sleep(3000);
                    System.out.println("Consumer get: " + goods.get());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    static class Goods{
        private PipedInputStream pis = new PipedInputStream();
        private PipedOutputStream pos = new PipedOutputStream(pis);
        private boolean bFull = false;

        Goods() throws IOException {
        }
        //放入商品
        public synchronized void put(int i) throws IOException, InterruptedException {
            //不是满的状态（商品为空时）
            if (!bFull){
                this.pos.write(i);
                this.bFull = true;
                //唤醒消费者线程
                this.notifyAll();
            }
            //使生产者线程进入等待状态
            this.wait();
        }

        //获取商品
        public synchronized int get() throws InterruptedException, IOException {
            //如果为商品为空，则消费者线程进入等待状态
            if (!bFull){
                this.wait();
            }
            bFull = false;
            int readValue = pis.read();
            //唤醒生产者线程
            this.notifyAll();
            return readValue;
        }

    }
}
